package pri.damai.xiaowu.common.core.util;

import cn.hutool.core.convert.NumberChineseFormatter;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Date;
import java.util.Objects;

/**
 * 时间转化工具
 * @Desc
 * @Author DaMai
 * @Date 2021/5/11 16:36
 * 但行好事，莫问前程。
 */
public class DateUtils {

    public static final String HH_MM_SS_24 = "HH:mm:ss";
    public static final String HH_MM_SS_12 = "hh:mm:ss";
    public static final String HHMMSS = "HHmmss";

    /** 时间格式 : 2021-10-11 */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYYMMDD = "yyyyMMdd";

    /** 时间格式 : 2021-10-11 12:12:30 */
    public static final String YYYY_MM_DD_HH_MM_SS = YYYY_MM_DD + " " + HH_MM_SS_24;
    public static final String YYYYMMDDHHMMSS = YYYYMMDD + HHMMSS;

    /** 时间偏移量 */
    public static final String ZONE_OFF_SET_8 = "+8";

    /** 时间格式 : 2021年10月11日 (周五) 上午 12:12:30 */
    public static String STANDARD_DATE_TIME_STYLE = "%s年%s月%s日 (周%s) %s";


    public static String AM_CN = "上午";
    public static String PM_CN = "下午";

    /**
     * 格式化时间
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 10:51
     */
    public static String formatDateTime(LocalDateTime localDateTime) {
        return formatDateTime(localDateTime, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 标准格式化时间(24小时制)
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 17:18
     */
    public static String standardFormatDate(LocalDateTime localDateTime) {
        return standardFormatDate(localDateTime, false);
    }

    /**
     * 标准格式化时间
     * @apiNote 格式形式 2021年10月22日 (周五) 下午 05:05:42
     * @param localDateTime 时间
     * @param is12 是否 12小时制
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 17:17
     */
    public static String standardFormatDate(LocalDateTime localDateTime, boolean is12) {
        String year = String.valueOf(localDateTime.getYear());
        String monthValue = String.valueOf(localDateTime.getMonthValue());
        String dayOfMonth = String.valueOf(localDateTime.getDayOfMonth());
        int week = localDateTime.getDayOfWeek().getValue();
        String weekDay = NumberChineseFormatter.format(week, false);
        String ampm = getAmPm(localDateTime);

        String timeFormatter = "";
        if (is12) {
            timeFormatter = HH_MM_SS_12;
        } else {
            timeFormatter = HH_MM_SS_24;
        }

        String timeStyle = localDateTime.toLocalTime().format(DateTimeFormatter.ofPattern(timeFormatter));

        return String.format(STANDARD_DATE_TIME_STYLE, year, monthValue, dayOfMonth,
                weekDay, ampm) + " " + timeStyle;
    }

    /**
     * 获取时间上午、下午
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 17:06
     */
    private static String getAmPm(LocalDateTime localDateTime) {
        return localDateTime.get(ChronoField.AMPM_OF_DAY) == 0 ? AM_CN : PM_CN;
    }

    /**
     * 格式化时间
     * @apiNote [附加描述]
     * @param localDate 日期
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 10:51
     */
    public static String formatDate(LocalDate localDate) {
        return formatDateTime(getLocalDateStartTime(localDate), YYYY_MM_DD);
    }

    /**
     * 格式化时间
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @param formatStr 格式化
     * @return java.lang.String
     * @author DaMai
     * @date 2021/10/22 9:59
     */
    public static String formatDateTime(LocalDateTime localDateTime, String formatStr) {
        if (Objects.isNull(formatStr) || Objects.isNull(localDateTime)) {
            return null;
        }
        return localDateTime.format(DateTimeFormatter.ofPattern(formatStr));
    }

    /**
     * 获取某天的开始时间
     * @apiNote [附加描述]
     * @param localDate 日期
     * @return java.time.LocalDateTime
     * @author DaMai
     * @date 2021/10/22 9:32
     */
    public static LocalDateTime getLocalDateStartTime(LocalDate localDate) {
        return Objects.isNull(localDate) ? null : LocalDateTime.of(localDate, LocalTime.MIN);
    }

    /**
     * 获取某天的结束时间
     * @apiNote [附加描述]
     * @param localDate 日期
     * @return java.time.LocalDateTime
     * @author DaMai
     * @date 2021/10/22 9:31
     */
    public static LocalDateTime getLocalDateEndTime(LocalDate localDate) {
        return Objects.isNull(localDate) ? null : LocalDateTime.of(localDate, LocalTime.MAX);
    }

    /**
     * 时间戳
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @return long 时间戳
     * @author DaMai
     * @date 2021/10/22 9:29
     */
    public static long asTimeStamp(LocalDateTime localDateTime) {
        return Objects.isNull(localDateTime) ? 0 : localDateTime.toInstant(ZoneOffset.of(ZONE_OFF_SET_8)).toEpochMilli();
    }

    /**
     * 时间戳 转 LocalDate
     * @apiNote [附加描述]
     * @param timeStamp 时间戳
     * @return java.time.LocalDate
     * @author DaMai
     * @date 2021/10/22 9:24
     */
    public static LocalDate asLocalDate(long timeStamp) {
        return asLocalDateTime(timeStamp).toLocalDate();
    }

    /**
     * 时间戳 转 LocalDateTime
     * @apiNote [附加描述]
     * @param timeStamp 时间戳
     * @return java.time.LocalDateTime
     * @author DaMai
     * @date 2021/10/21 20:11
     */
    public static LocalDateTime asLocalDateTime(long timeStamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), ZoneId.systemDefault());
    }

    /**
     * LocalDate -> Date
     * @apiNote [附加描述]
     * @param localDate 日期
     * @return java.util.Date
     * @author DaMai
     * @date 2021/5/12 10:14
     */
    public static Date asDate(LocalDate localDate) {
        return localDate == null ? null : Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDateTime --> Date
     * @apiNote [附加描述]
     * @param localDateTime 时间
     * @return java.util.Date
     * @author DaMai
     * @date 2021/5/12 10:16
     */
    public static Date asDate(LocalDateTime localDateTime) {
        return localDateTime == null ? null : Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Date --> LocalDate
     * @apiNote [附加描述]
     * @param date 时间
     * @return java.time.LocalDate
     * @author DaMai
     * @date 2021/5/12 10:17
     */
    public static LocalDate asLocalDate(Date date) {
        return date == null ? null : Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * Date --> LocalDateTime
     * @apiNote [附加描述]
     * @param date 时间
     * @return java.time.LocalDateTime
     * @author DaMai
     * @date 2021/5/12 10:17
     */
    public static LocalDateTime asLocalDateTime(Date date) {
        return date == null ? null : Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    public static void main(String[] args) {
        String s = standardFormatDate(LocalDateTime.now(), true);
        System.out.println(s);
    }

}
